﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using com.cruxomatic.BusinessFacades;
using com.cruxomatic.configuration;
using com.cruxomatic.configuration.FeatureManager;
using com.cruxomatic.configuration.PasswordManager;
using com.cruxomatic.DTOs;
using com.cruxomatic.DTOs.Configuration;
using com.cruxomatic.exceptions;
using com.cruxomatic.logging;
using com.cruxomatic.logging.Enums;
using com.cruxomatic.security;
using com.cruxomatic.security.EncryptionAndHashing.Enums;
using com.cruxomatic.views;

namespace com.cruxomatic.controllers
{
    public class ResetPasswordAfterPasswordExpiredController
    {
        IResetPasswordAfterPasswordExpired _view = null;
        public ResetPasswordAfterPasswordExpiredController(IResetPasswordAfterPasswordExpired view)
        {
            _view = view;
        }

        public void NavigateToLoginPage()
        {
            NavigationController.OpenView("Login");
        }

        public void ResetPassword()
        {
            bool success = false;
            if (PasswordConfirmationOk())
            {
                if (IsCurrentPasswordMatched())
                {
                    if (ValidatePasswordWithLastSavedPassword())
                    {
                        try
                        {
                            IPasswordManager passwordManager = PasswordManagerFactory.GetPasswordManager();
                            passwordManager.ValidatePassword(_view.NewPassword);
                            SaveNewPassword();
                            success = true;
                        }
                        catch (PasswordException ex)
                        {
                            _view.ErrorDetails = CruxApplicationErrorManager.GetApplicationError("103", ex.Message);
                        }
                        catch (Exception ex)
                        {
                            ApplicationLogger.LogApplicationMessage(
                                ex.Message, ApplicationLogType.Database, ex.StackTrace);
                            _view.ErrorDetails = CruxApplicationErrorManager.GetApplicationError("101", ex.Message);
                        }
                    }
                }
                else
                    _view.ErrorDetails = CruxConfigurationManager.GetErrorInformation("914");
            }
            else
                _view.ErrorDetails = CruxApplicationErrorManager.GetApplicationError("802");
            if (success) NavigateToLoginPage();
        }

        private bool IsCurrentPasswordMatched()
        {
            ICruxSecurityManager cruxSecurityManager = CruxSecurityManagerFactory.GetSecurityManager();
            if (cruxSecurityManager.AuthenticateUser(_view.UserName, _view.CurrentPassWord))
                return true;
            else
                return false;
        }

        private void SaveNewPassword()
        {
            PasswordFacade passwordFacade = new PasswordFacade();
            PasswordStorageType passwordStorageType = CruxConfigurationManager.GetPasswordStorageType();
            int savedPasswordCount =
                Convert.ToInt32(CruxConfigurationManager.GetApplicationCustomSetting("NumberOfSavedPassword").Value);
            IFeatureManager featureManager = FeatureManagerFactory.GetFeatureManager();
            bool isFeatureSupported = featureManager.IsFeatureSupported("SavePreviousPasswords");
            passwordFacade.ResetPassword(_view.UserName, _view.NewPassword, passwordStorageType, savedPasswordCount, isFeatureSupported);
        }

        private bool ValidatePasswordWithLastSavedPassword()
        {
            IFeatureManager featureManager = FeatureManagerFactory.GetFeatureManager();
            if (featureManager.IsFeatureSupported("SavePreviousPasswords"))
            {
                int savedPasswordCount =
                Convert.ToInt32(CruxConfigurationManager.GetApplicationCustomSetting("NumberOfSavedPassword").Value);
                PasswordFacade facade = new PasswordFacade();
                PasswordStorageType passwordStorageType = CruxConfigurationManager.GetPasswordStorageType();
                if (facade.IsPasswordUsedBefore(_view.NewPassword, _view.UserName, passwordStorageType, savedPasswordCount))
                {
                    ErrorInformation error = CruxApplicationErrorManager.GetApplicationError("912");
                    error.ShortDescription = error.ShortDescription.Replace("{0}", Convert.ToString(savedPasswordCount));
                    error.ErrorDescription = error.ErrorDescription.Replace("{0}", Convert.ToString(savedPasswordCount));
                    error.RecommendedAction = error.RecommendedAction.Replace("{0}", Convert.ToString(savedPasswordCount));
                    error.ProbableCause = error.ProbableCause.Replace("{0}", Convert.ToString(savedPasswordCount));
                    _view.ErrorDetails = error;
                    return false;
                }
                else
                    return true;
            }
            else
                return true;
        }

        private bool PasswordConfirmationOk()
        {
            if (_view.NewPassword != _view.ConfirmedNewPassword)
            {
                return false;
            }
            else
            {
                return true;
            }
        }
    }
}
